#pragma once
#include "config.h"

typedef struct _tcb_node_t{
	struct _tcb_node_t *prev;
	struct _tcb_node_t *next;
	struct _tcb_t *tcb;
} tcb_node_t;

typedef struct _tcb_list_t{
	struct _tcb_node_t *head;
	struct _tcb_node_t *tail;
} tcb_list_t;

typedef struct _tcb_t{
	void (*task_func)(void *);
	void *arg;

	uint32_t prio:3;// task priority
	uint32_t malloc_type:1; // malloc type
	uint32_t reserved:2; // reserved
	uint32_t notify_state:2; // notify state
	uint32_t notify_value:24; // notify value

	uint32_t timeout;	// task sleep timeout
	tcb_list_t *state_list; // task state list
	tcb_node_t node;
} tcb_t, task_t;

typedef enum {
	TASK_PRIO_IDLE = 0,
	TASK_PRIO_LOWEST,
	TASK_PRIO_LOWER,
	TASK_PRIO_LOW,
	TASK_PRIO_NORMAL,
	TASK_PRIO_HIGH,
	TASK_PRIO_HIGHER,
	TASK_PRIO_HIGHEST,
	TASK_PRIO_MAX,
} task_prio_e;

typedef enum{
	NOTIFY_NONE = 0, // none notify
	NOTIFY_WAIT,	 // waiting for notification
	NOTIFY_RECE,	 // received notification
} notify_state_e;

typedef enum{
	ACTION_NO = 0,			// Binary signal type, no value operation
	ACTION_SET_BITS,		// Event group type, set bits operation
	ACTION_INCREMENT,		// Counting signal type, auto-increment operation
	ACTION_OVERWRITE,		// Email address type, overwrite the previous value
	ACTION_OVERWRITE_CHECK, // queue type, check if the previous value has been read by the task
} notify_action_e;



void printf_task_list(void);

// idle task
__weak void task_idleTask(void);

void task_sched_process(void);

task_t* task_create(task_t* new_task, void (*task_func)(void *), void *arg, task_prio_e prio);
int task_delete(task_t* task);
int task_sleep(task_t* task, uint32_t timeout);
int task_suspend(task_t* task);
int task_wakeup(task_t* task);
int task_notifyWait(uint32_t Entry_CleanBits, uint32_t Exit_CleanBits, uint32_t *notify_value, uint32_t timeout);
int task_notify(task_t* task, uint32_t value, notify_action_e action, uint32_t *old_value);
int task_set_prio(task_t* task, task_prio_e prio);

